package org.box.metadata.cli;

import org.box.metadata.cli.MetaCommandLineParser.ParserType;
import org.box.metadata.cli.exception.ParseException;
import org.box.metadata.cli.util.HelpFormatter;
import org.box.metadata.shell.console.ConsoleShell;
import org.box.metadata.shell.exception.TerminatedException;

/**
 * <p>
 * Represents a facade API of the library and provides simplified methods to
 * working with the flowing modules:
 * 
 * <li> {@link MetaCommandLineParser}
 * <li> {@link HelpFormatter}
 * <li> {@link ConsoleShell}
 * 
 * </p>
 * 
 * @author <a href="mailto:alexander.box@gmail.com">Alexander Korobka</a>
 * 
 */
public final class MetaCli {

	/**
	 * Parses a list of arguments and instantiates an instance of the given
	 * application's configuration with injected values in the corresponding to
	 * given arguments.
	 * 
	 * @param args
	 *            - a list of arguments from the command line
	 * @param cfgClass
	 *            - the class of the configuration
	 * 
	 * @return a new instance of the configuration
	 * @throws ParseException
	 *             if command line parsing errors
	 */
	public static <T> T parse(String[] args, Class<T> cfgClass)
			throws ParseException {
		return new MetaCommandLineParser<T>(cfgClass).parse(args);
	}

	/**
	 * Parses a list of arguments and instantiates an instance of the given
	 * application's configuration with injected values in the corresponding to
	 * given arguments.
	 * 
	 * @param args
	 *            - a list of arguments from the command line
	 * @param cfgClass
	 *            - the class of the configuration
	 * @param parserType
	 *            - the type of the parser to use for
	 * 
	 * @return a new instance of the configuration
	 * @throws ParseException
	 *             if command line parsing errors
	 */
	public static <T> T parse(String[] args, Class<T> cfgClass,
			ParserType parserType) throws ParseException {
		return new MetaCommandLineParser<T>(cfgClass, parserType).parse(args);
	}

	/**
	 * Prints help for the given configuration
	 * 
	 * @param cfgClass
	 *            - the class of the configuration
	 */
	public static <T> void printHelp(Class<T> cfgClass) {
		new HelpFormatter(cfgClass).printHelp();
	}

	/**
	 * Runs the Shell with a list of arguments and perform exit after completion
	 * 
	 * @param args
	 *            - a list of arguments for the application
	 * 
	 * @throws TerminatedException
	 *             if the application terminates
	 */
	public static <T> void runAndExit(String[] args, Class<T> cfgClass) throws TerminatedException {
		new ConsoleShell(cfgClass).runAndExit(args);
	}

	/**
	 * Runs the Shell with a list of arguments.
	 * 
	 * @param args
	 *            - a list of arguments for the application
	 *            
	 * @throws TerminatedException
	 *             if the application terminates
	 */
	public static <T> void runShell(String[] args, Class<T> cfgClass)
			throws TerminatedException {
		new ConsoleShell(cfgClass).run(args);
	}

}
